package com.yst.webplugin.additional.transform;

import org.apache.commons.lang3.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;

public class TransformConfigUtil {
    public static TransformConfigItem fromAnnotation(Transform annotation){
        try {
            if (StringUtils.isNotEmpty(annotation.dictionaryName())) {
                return new TransformConfigItem(annotation.sourceField(),
                        annotation.destField(), annotation.dictionaryName());
            }
            return new TransformConfigItem(annotation.sourceField(),
                    annotation.destField(),annotation.dictClass().getName());

        }
        catch (Exception e){
            e.printStackTrace();
            //ignore exception
        }
        return null;
    }
    public static List<TransformConfigItem> fromAnnotation(Transform.List annotation){
        List<TransformConfigItem> result=new ArrayList<>();
        Transform[] transforms=annotation.value();
        for(Transform transform:transforms){
            TransformConfigItem configItem=fromAnnotation(transform);
            if (Objects.nonNull(configItem)) {
                result.add(configItem);
            }
        }
        return result;
    }

    private static final Map<Field,List<TransformConfigItem>> fieldCache=
            new HashMap<>();
    public static List<TransformConfigItem> fromField(Field field){
        Transform transform= field.getAnnotation(Transform.class);

        return fieldCache.computeIfAbsent(field,(f)->{
            List<TransformConfigItem> result=new ArrayList<>();
            if (Objects.nonNull(transform)){
                TransformConfigItem transformConfigItem=fromAnnotation(transform);
                if (StringUtils.isEmpty(transformConfigItem.getNameField())){
                    transformConfigItem.setNameField(field.getName());
                }

                result.add(transformConfigItem);
            }
            return result;
        });
    }

    private static final Map<Class,List<TransformConfigItem>> classCache=
            new HashMap<>();
    public static List<TransformConfigItem> fromClass(Class clazz) {
        Annotation annotation = clazz.getAnnotation(Transform.class);
        Transform transform = (Transform) annotation;
        Transform.List list = (Transform.List)clazz.getAnnotation(Transform.List.class);
        if (Objects.isNull(transform)&&Objects.isNull(list)){
            return Collections.emptyList();
        }
        return classCache.computeIfAbsent(clazz, (key) -> {
            List<TransformConfigItem> result = new ArrayList<>();

            if (Objects.nonNull(annotation)) {
                TransformConfigItem transformConfigItem = fromAnnotation(transform);
                if (Objects.nonNull(transformConfigItem)) {
                    if (!StringUtils.isEmpty(transformConfigItem.getIdField())) {
                        result.add(transformConfigItem);
                    } else {
                        throw new RuntimeException(String.format("invalid annotation Transform of the class %s,need config source field!", clazz.getName()));
                    }
                    if (!StringUtils.isEmpty(transformConfigItem.getNameField())) {
                        result.add(transformConfigItem);
                    } else {
                        throw new RuntimeException(String.format("invalid annotation Transform of the class %s,need config name field!", clazz.getName()));
                    }
                }
            }

            if (Objects.nonNull(list)) {
                result.addAll(fromAnnotation(list));
            }
            return result;
        });
    }
}
